#include "factmanager.h"
#include "databasemanager.h"
#include <QDebug>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>

/**
 * @brief FactManager类的构造函数
 * @param parent 父对象，默认为nullptr
 */
FactManager::FactManager(QObject *parent)
    : QObject(parent), m_dbManager(nullptr)
{
}

/**
 * @brief 添加事实
 * @param fact 要添加的事实
 * @return 如果事实不存在且添加成功则返回true，否则返回false
 * 
 * 如果事实为空或已存在，则添加失败
 */
bool FactManager::addFact(const QString &fact)
{
    // 检查事实是否为空
    if (fact.isEmpty()) {
        return false;
    }

    // 去除首尾空格
    QString trimmedFact = fact.trimmed();
    
    // 检查事实是否已存在
    if (m_facts.contains(trimmedFact)) {
        return false; // 事实已存在
    }

    // 添加到事实集合和顺序列表中
    m_facts.insert(trimmedFact);
    m_factOrder.append(trimmedFact);
    
    // 发送信号
    emit factAdded(trimmedFact);
    emit factsChanged();
    return true;
}

/**
 * @brief 移除事实
 * @param fact 要移除的事实
 * @return 如果事实存在且移除成功则返回true，否则返回false
 * 
 * 如果事实不存在，则移除失败
 */
bool FactManager::removeFact(const QString &fact)
{
    // 去除首尾空格
    QString trimmedFact = fact.trimmed();
    
    // 检查事实是否存在
    if (!m_facts.contains(trimmedFact)) {
        return false; // 事实不存在
    }

    // 从事实集合和顺序列表中移除
    m_facts.remove(trimmedFact);
    m_factOrder.removeAll(trimmedFact);
    
    // 发送信号
    emit factRemoved(trimmedFact);
    emit factsChanged();
    return true;
}

/**
 * @brief 清空所有事实
 */
void FactManager::clearFacts()
{
    // 如果事实集合不为空，则清空并发送信号
    if (!m_facts.isEmpty()) {
        m_facts.clear();
        m_factOrder.clear();
        emit factsChanged();
    }
}

/**
 * @brief 检查事实是否存在
 * @param fact 要检查的事实
 * @return 如果事实存在则返回true，否则返回false
 */
bool FactManager::hasFact(const QString &fact) const
{
    return m_facts.contains(fact.trimmed());
}

/**
 * @brief 获取所有事实
 * @return 包含所有事实的字符串列表，按添加顺序排列
 */
QStringList FactManager::getAllFacts() const
{
    return m_factOrder; // 返回按添加顺序排列的事实列表
}

/**
 * @brief 获取事实数量
 * @return 事实的数量
 */
int FactManager::getFactCount() const
{
    return m_facts.size();
}

/**
 * @brief 批量添加事实
 * @param facts 要添加的事实列表
 * 
 * 遍历事实列表，逐个添加，如果有任何事实被成功添加，则发送factsChanged信号
 */
void FactManager::addFacts(const QStringList &facts)
{
    bool changed = false;
    
    // 遍历事实列表，逐个添加
    for (const QString &fact : facts) {
        if (addFact(fact)) {
            changed = true;
        }
    }
    
    // 如果有任何事实被成功添加，则发送信号
    if (changed) {
        emit factsChanged();
    }
}

/**
 * @brief 将事实保存到文件
 * @param filename 文件名
 * @return 如果保存成功则返回true，否则返回false
 * 
 * 使用JSON格式保存事实，保持事实的添加顺序
 */
bool FactManager::saveFactsToFile(const QString &filename) const
{
    // 打开文件进行写入
    QFile file(filename);
    if (!file.open(QIODevice::WriteOnly)) {
        qDebug() << "无法打开文件进行写入：" << filename;
        return false;
    }

    // 创建JSON数组，按顺序添加所有事实
    QJsonArray factsArray;
    for (const QString &fact : m_factOrder) {
        factsArray.append(fact);
    }

    // 创建JSON对象，将事实数组作为其属性
    QJsonObject rootObj;
    rootObj["facts"] = factsArray;

    // 创建JSON文档并写入文件
    QJsonDocument doc(rootObj);
    file.write(doc.toJson());
    file.close();
    return true;
}

/**
 * @brief 从文件加载事实
 * @param filename 文件名
 * @return 如果加载成功则返回true，否则返回false
 * 
 * 从JSON格式文件中加载事实，保持事实的添加顺序
 */
bool FactManager::loadFactsFromFile(const QString &filename)
{
    // 打开文件进行读取
    QFile file(filename);
    if (!file.open(QIODevice::ReadOnly)) {
        qDebug() << "无法打开文件进行读取：" << filename;
        return false;
    }

    // 读取文件内容并解析为JSON文档
    QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
    file.close();

    // 检查JSON文档是否为对象
    if (!doc.isObject()) {
        return false;
    }

    // 获取JSON对象和事实数组
    QJsonObject rootObj = doc.object();
    QJsonArray factsArray = rootObj["facts"].toArray();

    // 清空现有事实
    clearFacts();

    // 遍历事实数组，逐个添加
    for (const QJsonValue &value : factsArray) {
        addFact(value.toString());
    }

    return true;
}

/**
 * @brief 设置数据库管理器
 * @param dbManager 数据库管理器指针
 */
void FactManager::setDatabaseManager(DatabaseManager *dbManager)
{
    m_dbManager = dbManager;
}

/**
 * @brief 从数据库加载特征
 * @return 如果加载成功则返回true，否则返回false
 */
bool FactManager::loadFeaturesFromDatabase()
{
    if (!m_dbManager) {
        qDebug() << "数据库管理器未设置";
        return false;
    }
    
    // 从数据库获取所有特征
    m_availableFeatures = m_dbManager->getAllFeatures();
    
    // 发送特征变化信号
    emit featuresChanged();
    
    qDebug() << "从数据库加载特征完成，共加载" << m_availableFeatures.size() << "个特征";
    return true;
}

/**
 * @brief 获取所有可用特征
 * @return 包含所有可用特征的字符串列表
 */
QStringList FactManager::getAvailableFeatures() const
{
    return m_availableFeatures;
}